#include "Zigbee3ListXml.h"
#include "unistd.h"
Zigbee3ListXml::Zigbee3ListXml()
{
    
}

bool Zigbee3ListXml::parser()
{
    m_zigbee3List.clear();
    if(!this->check())
    {
        return false;
    }
    QFile file(m_path);
    file.open(QFile::ReadOnly | QFile::Text);
    QDomDocument doc;
    doc.setContent(&file);
    file.close();

    QDomElement root = doc.documentElement();
    QDomNode rootChild = root.firstChild();

    while (!rootChild.isNull())
    {
        if(rootChild.toElement().tagName() == "Zigbee3")   //解析Device
        {
            QDomNode zigbeeChild = rootChild.toElement().firstChild();
            Zigbee3Struct zigbee;
            zigbee.setType(0x00);
            while(!zigbeeChild.isNull())
            {
                if (zigbeeChild.toElement().tagName() == "MAC")         //获取Zigbee的MAC地址
                {
                    QString mac = zigbeeChild.toElement().text().remove(" ");
                    zigbee.setMac(QByteArray::fromHex(mac.toLatin1()));

                }
                else if (zigbeeChild.toElement().tagName() == "NWK")    //获取Zigbee的NWK地址
                {
                    QString nwk = zigbeeChild.toElement().text().remove(" ");
                    zigbee.setNwk(QByteArray::fromHex(nwk.toLatin1()));

                }
                else if (zigbeeChild.toElement().tagName() == "AddressList") //获取Zigbee的点位地址列表
                {
                    QStringList addressList = zigbeeChild.toElement().text().split(",");
                    QList<ControlPointStruct> pointList;
                    foreach (const QString &address, addressList)
                    {
                        ControlPointStruct point;
                        point.setAddress(address.toUInt());
                        pointList.append(point);
                    }
                    zigbee.setPointList(pointList);
                }
                else if (zigbeeChild.toElement().tagName() == "DeviceType")    //获取Zigbee的NWK地址
                {
                    QString Type = zigbeeChild.toElement().text().remove(" ");

                    zigbee.setType(Type.toInt(0,16));
                }
                else if (zigbeeChild.toElement().tagName() == "PointValue")    //获取Zigbee的value
                {
                    QString PointValue = zigbeeChild.toElement().text().remove(" ");
                    qDebug()<<"zib3Atype="<<PointValue;
                    qDebug()<<"zib3Btype="<<PointValue.toLatin1().at(0);
                    qDebug()<<"zib3Ctype="<<PointValue.toLatin1();
                    qDebug()<<"zib3dtype="<<PointValue.toLatin1().toInt(0,10);
                    if(!zigbeeChild.toElement().text().size()==0)
                    {
                    qDebug()<<"SetPointValue success";
                    zigbee.setPointValue(PointValue.toLatin1());
                    }
                    qDebug()<<"zib3etype="<<zigbee.pointValue();
                    qDebug()<<"zib3etype="<<zigbee.pointValue().toInt(0,10);
                     qDebug()<<"zib3ztype="<<zigbee.pointValue().at(0);
                }
                else if (zigbeeChild.toElement().tagName() == "DeviceName")    //获取Zigbee的NWK地址
                {
                    QString Name = zigbeeChild.toElement().text().remove(" ");

                    zigbee.setName(Name);
                }


                zigbeeChild = zigbeeChild.nextSibling();
            }
            m_zigbee3List.append(zigbee);
        }
        rootChild = rootChild.nextSibling();
    }
    return true;
}

bool Zigbee3ListXml::modify(const quint8 &number, const Zigbee3Struct &zigbee)
{
    u_int8_t repeatFlag=0;
    u_int8_t modifyFlag=0;
    static QMutex mutex;
    mutex.lock();
    if(!this->check())
    {
        return false;
    }

    QFile file(m_path);
    file.open(QFile::ReadOnly | QFile::Text);
    QDomDocument doc;
    doc.setContent(&file);
    file.close();

    QDomElement root=doc.documentElement();
    QDomNode rootChild = root.firstChild();

    Zigbee3Struct completeZigbee = zigbee;
    for(quint16 index=0; index<m_zigbee3List.size(); index++)
    {
        Zigbee3Struct tempZigbee = m_zigbee3List.at(index);
        if(tempZigbee.mac() == completeZigbee.mac())
        {
            if(number != 0)
            {
                QList<ControlPointStruct> pointList = tempZigbee.pointList();
                pointList.append(completeZigbee.pointList());
                completeZigbee.setPointList(pointList);
            }
            m_zigbee3List.removeAt(index);
            break;
        }
    }

    m_zigbee3List.append(completeZigbee);


    while (!rootChild.isNull())
    {
        if(rootChild.toElement().tagName() == "Zigbee3")   //解析Device
        {
            QDomNodeList nodeList = rootChild.childNodes();
            for(int i=0; i<nodeList.size(); i++)
            {
                QDomNode node = nodeList.at(i);
                if(node.toElement().tagName() == "MAC")
                {
                   // QByteArray mac = QByteArray::fromHex(node.toElement().text().remove(" ").toLatin1());
                    QByteArray mac = node.toElement().text().remove(" ").toUtf8();
                    qDebug()<<"mac="<<mac;
                    qDebug()<<"completeZigbee mac="<<completeZigbee.mac().toHex().toUpper();
                    if(mac == completeZigbee.mac().toHex().toUpper())
                    {
                        qDebug()<<"------------*****--------------------XML have same MAC";
                       // root.removeChild(rootChild);
                        modifyFlag=1;
                        repeatFlag=1;

                        break;
                    }
                }
            }
            if(modifyFlag==1)
            {
                for(int i=0; i<nodeList.size(); i++)
                {
                    QDomNode node = nodeList.at(i);
                    if(node.toElement().tagName() == "NWK")
                    {
                       QDomNode oldNode=node.toElement().firstChild();
                       QString nwk = completeZigbee.nwk().toHex().toUpper();
                       node.toElement().firstChild().setNodeValue(nwk);
                       QDomNode newNode=node.toElement().firstChild();
                       node.replaceChild(newNode,oldNode);
                       modifyFlag=0;
                    }
                }
            }
        }
        rootChild = rootChild.nextSibling();
    }

    if(repeatFlag==0)
    {
        qDebug()<<"------------*****--------------------XML have new MAC";
        QDomElement zigbeeElement = doc.createElement("Zigbee3");
        QDomText text;
        QDomElement macElement = doc.createElement("MAC");
        QString mac = completeZigbee.mac().toHex().toUpper();
        int length = mac.length()/2;
        for(int i=1; i<length; i++)
        {
            mac.insert(2*i+i-1," ");
        }
        text = doc.createTextNode(mac);
        macElement.appendChild(text);
        zigbeeElement.appendChild(macElement);

        QDomElement nwkElement = doc.createElement("NWK");
        QString nwk = completeZigbee.nwk().toHex().toUpper();
        length = nwk.length()/2;
        for(int i=1; i<length; i++)
        {
            nwk.insert(2*i+i-1," ");
        }
        text = doc.createTextNode(nwk);
        nwkElement.appendChild(text);
        zigbeeElement.appendChild(nwkElement);

        root.appendChild(zigbeeElement);
    }
//    QDomElement addressListElement = doc.createElement("AddressList");

 //   QStringList tempAddressList;
 //   for(int i=0; i<completeZigbee.pointList().size(); i++)
 //   {
//        tempAddressList.append(QString::number(completeZigbee.pointList().at(i).address()));
//    }
 //   QString addressList = tempAddressList.join(",");

//    text = doc.createTextNode(addressList);
//    addressListElement.appendChild(text);
//    zigbeeElement.appendChild(addressListElement);



//    QDomElement deviceTypeElement = doc.createElement("DeviceType");
//    QString typeTip;
//    typeTip.clear();
//    text = doc.createTextNode(typeTip);
//    deviceTypeElement.appendChild(text);
//   zigbeeElement.appendChild(deviceTypeElement);

//    QDomElement SpecialConfigurationElement = doc.createElement("PointValue");
//    QString specialConfigurationTip;
//    specialConfigurationTip.clear();
//    text = doc.createTextNode(specialConfigurationTip);
 //   SpecialConfigurationElement.appendChild(text);
 //   zigbeeElement.appendChild(SpecialConfigurationElement);

//    QDomText texta;
 //   QDomElement NamenElement = doc.createElement("Name");
//    QString NameTip;
//    NameTip.clear();
//    texta = doc.createTextNode(NameTip);
//    NamenElement.appendChild(texta);
//    zigbeeElement.appendChild(NamenElement);

    file.open(QFile::WriteOnly|QFile::Truncate); //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
    QTextStream outStream(&file);
    doc.save(outStream,4); //缩进4格
    file.flush();
    fsync(file.handle());
    file.close();
    m_zigbee3List.clear();

    mutex.unlock();
    parser();
    return true;
}


bool Zigbee3ListXml::SetData(Zigbee3Struct Struct)
{
    quint8 SetType=0;
    quint8 SetAddr=0;
    quint8 SetName=0;

    Zigbee3Struct completeZigbee=Struct;
    if(!this->check())
    {
        return false;
    }

    QFile file(m_path);
    file.open(QFile::ReadOnly | QFile::Text);
    QDomDocument doc;
    doc.setContent(&file);
    file.close();

    QDomElement root=doc.documentElement();
    QDomNode node = root.firstChild();
    qDebug()<<"STNWK="<<Struct.nwk();
    while (!node.isNull())
    {
           if(node.toElement().tagName() == "Zigbee3")
           {
               QDomNode nodeChild=node.firstChild();
               while(!nodeChild.isNull())
               {
                   if(nodeChild.toElement().tagName() == "NWK")
                   {
                       qDebug()<<"NWK is going~~~~~~~~~~~~~~~~~~";
                       QString xml_NWK= nodeChild.toElement().text().remove(QRegExp("\\s"));
                       qDebug()<<"packNWK="<<QString(Struct.nwk());
                       qDebug()<<"packNWK="<<xml_NWK;
                       if(xml_NWK==QString(Struct.nwk()))
                       {
                           qDebug()<<"NWK is ok~~~~~~~~~~~~~~~~~~";
                           while(!nodeChild.isNull())
                           {
                               if(nodeChild.toElement().tagName() == "DeviceType")
                                 {
                                   SetType=1;
                                  qDebug()<<"now check type";
                                  QString xml_DeviceType= nodeChild.toElement().text().remove(QRegExp("\\s"));
                                  qDebug()<<"xmltype="<<xml_DeviceType;
                                   qDebug()<<"cmdtype="<<QString(Struct.type());
                                   if(xml_DeviceType!=QString::number(Struct.type()))
                                    {
                                      qDebug()<<"But turn Type";
                                      QDomNode oldType=nodeChild;
                                      oldType.firstChild().setNodeValue(QString::number(Struct.type()));
                                      QDomNode newType=oldType.firstChild();
                                      oldType.replaceChild(newType,oldType);
                                   }
                                }

                               else if(nodeChild.toElement().tagName() == "AddressList")
                               {
                                   SetAddr=1;
                                    qDebug()<<"now check type";
                                    QStringList tempAddressList;
                                    for(int i=0; i<completeZigbee.pointList().size(); i++)
                                    {
                                        tempAddressList.append(QString::number(completeZigbee.pointList().at(i).address()));
                                        qDebug()<<"address="<<completeZigbee.pointList().at(i).address();
                                    }
                                    QString addressList = tempAddressList.join(",");
                                    QDomNode oldAddress=nodeChild;
                                    oldAddress.firstChild().setNodeValue(addressList);
                                    QDomNode newAddress=oldAddress.firstChild();
                                    oldAddress.replaceChild(newAddress,oldAddress);

                               }

                               else if(nodeChild.toElement().tagName() == "DeviceName")
                               {
                                   SetName=1;
                                   qDebug()<<"now check name";
                                   qDebug()<<"now check type";
                                   QString xml_Name= nodeChild.toElement().text().remove(QRegExp("\\s"));
                                   qDebug()<<"xmltype="<<xml_Name;
                                    qDebug()<<"cmdtype="<<Struct.name();
                                    if(xml_Name!=Struct.name())
                                     {
                                       qDebug()<<"But turn Name";
                                       QDomNode oldName=nodeChild;
                                       oldName.firstChild().setNodeValue(Struct.name());
                                       QDomNode newName=oldName.firstChild();
                                       oldName.replaceChild(newName,oldName);
                                    }
                               }

                               nodeChild=nodeChild.nextSibling();
                           }
                           if(SetType==0)
                           {
                               qDebug()<<"set NOW type1="<<Struct.type();
                                qDebug()<<"set NOW type2="<<QString(Struct.type());

                           QDomElement deviceTypeElement = doc.createElement("DeviceType");
                           QString typeTip;
                           QDomText typeText;
                           typeTip=QString(QString::number(Struct.type()));
                           typeText = doc.createTextNode(typeTip);
                           deviceTypeElement.appendChild(typeText);
                           node.toElement().appendChild(deviceTypeElement);
                           }
                           if(SetAddr==0)
                           {
                               qDebug()<<"set addr";
                               QDomElement addressListElement = doc.createElement("AddressList");
                               QDomText addrText;
                               QStringList tempAddressList;
                               for(int i=0; i<completeZigbee.pointList().size(); i++)
                               {
                                   tempAddressList.append(QString::number(completeZigbee.pointList().at(i).address()));
                                   qDebug()<<"address="<<completeZigbee.pointList().at(i).address();
                               }
                               QString addressList = tempAddressList.join(",");
                               addrText = doc.createTextNode(addressList);
                               addressListElement.appendChild(addrText);
                               node.toElement().appendChild(addressListElement);
                           }
                           if(SetName==0)
                           {
                               qDebug()<<"set NOW Name="<<Struct.name();

                           QDomElement deviceNameElement = doc.createElement("DeviceName");
                           QString NameTip;
                           QDomText NameText;
                           NameTip=Struct.name();
                           NameText = doc.createTextNode(NameTip);
                           deviceNameElement.appendChild(NameText);
                           node.toElement().appendChild(deviceNameElement);
                           }


                       }

                   }
                   nodeChild=nodeChild.nextSibling();
               }

           }
        node = node.nextSibling();
    }

        file.open(QFile::WriteOnly|QFile::Truncate); //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
        QTextStream outStream(&file);
        doc.save(outStream,4); //缩进4格
        file.flush();
        file.close();
        m_zigbee3List.clear();
        parser();
        return true;

}

bool Zigbee3ListXml::SetDelete(QString nwk)
{
    if(!this->check())
    {
        return false;
    }

    QFile file(m_path);
    file.open(QFile::ReadOnly | QFile::Text);
    QDomDocument doc;
    doc.setContent(&file);
    file.close();

    QDomElement root=doc.documentElement();
    QDomNode node = root.firstChild();
    qDebug()<<"STNWK="<<nwk;
    while (!node.isNull())
    {
           if(node.toElement().tagName() == "Zigbee3")
           {
               QDomNode nodeChild=node.firstChild();
               while(!nodeChild.isNull())
               {
                   if(nodeChild.toElement().tagName() == "NWK")
                   {
                       qDebug()<<"NWK is going~~~~~~~~~~~~~~~~~~";
                       QString xml_NWK= nodeChild.toElement().text().remove(QRegExp("\\s"));
                       qDebug()<<"packNWK="<<xml_NWK;
                       if(xml_NWK==nwk)
                       {
                           root.removeChild(node);
                           file.open(QFile::WriteOnly|QFile::Truncate); //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
                           QTextStream outStream(&file);
                           doc.save(outStream,4); //缩进4格
                           file.flush();
                           file.close();
                           m_zigbee3List.clear();
                           parser();

                           return true;
                       }


                   }
                   nodeChild=nodeChild.nextSibling();
               }
           }
           node=node.nextSibling();
    }
    return false;
}

bool Zigbee3ListXml::clear()
{
    if(!this->clearAllNode())
    {
        return false;
    }

    m_zigbee3List.clear();
    return true;
}

QList<Zigbee3Struct> Zigbee3ListXml::zigbeeList(const QList<ControlPointStruct> &sourcePointList)
{
    QList<Zigbee3Struct> zigbeeList;
    foreach (const Zigbee3Struct &zigbee, m_zigbee3List)
    {
        Zigbee3Struct tempZigbee;
        tempZigbee.setMac(zigbee.mac());
        tempZigbee.setNwk(zigbee.nwk());
        tempZigbee.setType(zigbee.type());
        tempZigbee.setPointValue(zigbee.pointValue());
        QList<ControlPointStruct> controlPointList;
        foreach (const ControlPointStruct &point, zigbee.pointList())
        {
            foreach(const ControlPointStruct &sourcePoint, sourcePointList)
            {
                if(point.address() == sourcePoint.address())
                {
                    controlPointList.append(sourcePoint);
                    qDebug()<<"listvalue="<<sourcePoint.value();
                }
            }
        }

        if(!controlPointList.isEmpty())
        {
            int size = controlPointList.size();
            int count = (size + PointMaxSize - 1) / PointMaxSize;

            for (int i=0; i<count; i++)
            {
                QList<ControlPointStruct> tempPointList = controlPointList.mid(i*PointMaxSize, ((i+1)*PointMaxSize>size ? size:PointMaxSize*(i+1)));
                tempZigbee.setPointList(tempPointList);
                zigbeeList.append(tempZigbee);
            }
        }
    }
    return zigbeeList;
}
 QList<Zigbee3Struct>Zigbee3ListXml::zigbee3List()
 {
     return m_zigbee3List;
 }

 
QByteArray Zigbee3ListXml::GetZigbeeVersion()
{
    QByteArray GetVersionData;
    GetVersionData.append(0xa5);
    GetVersionData.append(0xaa);
    GetVersionData.append(0x5a);
    GetVersionData.append(0xa6);
    return GetVersionData;
}

void Zigbee3ListXml::SetZigbeeVersion(QByteArray version)
{
    m_ZigbeeVersion=version;
}

QByteArray Zigbee3ListXml::ZigbeeVersion()
{
    return m_ZigbeeVersion;
}
